<?php  

/**
* Class SeparateTags
* Separate tags from article, and replace them by the specified strings.
* This class is help to produce internal links.
*
* @auth TIGER <ji.xiaod@gmail.com>
* @version  0.1
*/

class SeparateTags
{
	/**
	* Version.
	*/
	const VERSION = '0.1';	
	
	/**
	* Source string charset
	*/
	public $sourceCharset = 'utf-8';
		
	/**
	 *	Target string charset 
	 */	
	public $targetCharset = 'utf-8';

	/**
	*	Tags from table es_tags to separate tags from an article 
	*/ 	
	private $tagsArray = array();

	
	/**
	*  The source string to do
	*/
	private $sourceString = '';

	
	/**
	*	Tags will be replace by
	*/
	public $replaceString = '';

	
	/**
	*	Just the separate by punctuation 
	*/
	public $simpleResultArray = array();
	
	
	/**
	*   Final separate result array
	*/
	public $finallyResultArray = array();
	
	
	/**
	* Initialize a SeparateTags Application.
	*
	* @param Array $config the application configuration
	*/	
	public function __construct($tagsArray,$sourceString,$sourceChartset='utf-8',$targetCharset='utf-8')
	{
		$this->setTagsArray($tagsArray);			
		$this->setSourceString($sourceString);
		$this->setSourceCharset($sourceChartset);
		$this->setTargetChatset($targetCharset);				
	}
		
	/**
	* Set tags array
	* 
	* @param  $tagArray
	*/
	public function setTagsArray($tagArray)
	{
		$this->tagsArray = $tagArray;
	}
	 
	/**
	*	Set source string
	* 
	* @param  $sourceString
	*/
	public function setSourceString($sourceString)
	{
		$this->sourceString = $sourceString; 
	}

	/**
	*	Set source string charset 
	* 
	* @param	$sourceCharset 
	*/
	public function setSourceCharset($sourceCharset)
	{
		$this->sourceCharSet = $sourceCharset;
	}

	/**
	*	Set	target string charset
	* 
	* @param $targetCharset
	*/
	public function setTargetChatset($targetCharset)
	{
		$this->targetChatset = $targetCharset;
	}
	 
	/**
	*	Use to set string which tags will be replaced  
	* 
	* @param  $repalce_str
	*/
	public function setReplaceString($repalceString)
	{		
		$this->replaceString = $repalceString;
	}

	/**
	*	Replace tags by specified string.  
	* 
	* @param $tag
	* @return $replaceString
	*/
	public function replaceTags($tag)
	{
		return '<a onclick=”javascript:getRelate($tag)”>$tag</a>';	
	}
	 
	/**
	*	 Separate tags from string and replace them. 	 
	* 
	* @param  $sourceString
	* @return  $targetString
	*/
	public function separateString()
	{		

		$this->sourceString .= chr(0).chr(32);
		$sbcArr = array();
		$j = 0;

		/**
		* 	$sbcArr mapping with ASCII 32~126
		*/
		for($i=0xFF00; $i < 0xFF5F; $i++)
		{
			$scb = 0x20 + $j;
			$j++;
			$sbcArr[$i] = $scb;
		}
		
		
		// var_dump($sbcArr);
		
		$strlen = strlen($this->sourceString);
		
		$ansiWordMatch = "[0-9a-z@#%\+\.-]";
        $notNumberMatch = "[a-z@#%\+]";
        $lastc = 1; //1 中/韩/日文, 2 英文/数字/符号('.', '@', '#', '+'), 3 ANSI符号 4 纯数字 5 非ANSI符号或不支持字符
		$s = 0;
		$onstr = '';
		// if(preg_match('/'.$ansiWordMatch.'/i', '2132sf',$matches)){var_dump($matches);}
		/**
		*	Simple separate string,get result below:
		*		1.Chinese words and other not ASCII codes.
		*		2.English words , numver, include all ASCII codes.
		*/
		for($i=0; $i<$strlen; $i++)
		{
			$c = $this->sourceString[$i].$this->sourceString[++$i];
			$cn = hexdec(bin2hex($c));
			$cn = isset($sbcArr[$cn]) ? $sbcArr[$cn] : $cn;
			// echo $c.'=>'.$cn.'<br/>';
			
			/**
			*   ASCII codes
			*/
			if($cn < 0x80)
			{
				 if( preg_match('/'.$ansiWordMatch.'/i', chr($cn)) )
                {
                    if( $lastc != 2 && $onstr != '') 
					{
                        $this->simpleResult[$s]['w'] = $onstr;
                        $this->simpleResult[$s]['t'] = $lastc;
                        $this->_deep_analysis($onstr, $lastc, $s, $optimize);
                        $s++;
                        $onstr = '';
                    }
                    $lastc = 2;
                    $onstr .= chr(0).chr($cn);
					}					
			}			
		}		
		
		
		/**
		*   After get simple tag array, continue to separate deeply.
		*/
		// deepSeparateString();

	}
	
	
	/**
	* Check if the word is a tag
	* 
	* @param $word
	* @return $boolean
	*/
	public function isTag($word)
	{
		return in_array($this->tagsArray,$word);
	}	 
	 
	/**
	*	
	* 
	* @param 
	* @return 
	*/
	

	/**
	* Separate chinese words. 
	* 
	* @param $chineseString
	* @return $strings
	*/
	public function deepSeparateString($chineseString)
	{
			
	
	}
	
	
	/**
	*	Match english words.
	*
	* @param
	* @return
	*/
	public function matchWordsEn()
	{
		$en_wordMatch = "[a-zA-Z]+";
		preg_match('/'.$en_WordMatch.'/i',$this->sourceString,$matches);
		var_dump($matches);
	}
	
	
	/**
	*	Match chinese words
	*
	* @param
	* @return
	*/
	public function matchWordsCn()
	{
		$cn_wordMatch = "[\u4e00-\u9fa5]+";
		preg_match('/'.$cn_wordMatch.'/',$this->sourceString,$matches);
		var_dump($matches);
	}
	
	
	/**
	*	Get simple result  divide by sentences.
	*
	* @param
	* @return
	*/
	 public function getSentencesDivide()
	 {
	 	
		/**
		*   Sign	0x20~0x2F, 0x3A~0x40, 0x5B~0x60, 0x7B~0x7E
		*/
		echo (0x7E - 0x20);
	 	// $signArr =array();
		// $j = 0;
		// for($i=0; $i < 0x7E-0x20; $i++)
		// {				
			// $scb = $i + $j;
			// $j++;
			// $signArr[$i] = $scb;
		// }
	 }
	 

	/**
	*	Check if the character is a sign.
	*
	* @param
	* @return
	*/
	public function isSign()
	{
		
	}	
	
	
	
	//
	public function simpleReplace()
	{
		$count = count($this->tagsArray);
		$resultString = '';
		for($i=0; $i<$count; $i++){
			$resultString = str_replace($this->tagsArray[$i],
			'<a href ="javascript:void(0)" onclick="javascript:getRelate(\''.$this->tagsArray[$i].'\')">'.$this->tagsArray[$i].'</a>',
			$this->sourceString);
			
		}
	}
	 
	 /**
	 *  Simple replace tags by using method str_replace.
	 *
	 * @param
	 * @return  $result
	 */
	 public function simpleRepalceTags()
	 {
		$result = array(
								'resultStr'=>'',
								'count'=>array()
								);
		$string = $this->sourceString;
		$tagArr = $this->_removeDuplicateTags($this->tagsArray);
		// var_dump($tagArr);
		// $tagArr = $this->tagsArray;
		$taglen = count($tagArr);
		for($i=0; $i<$taglen; $i++){
			$result['resultStr'] = str_replace($tagArr[$i],'<a href ="javascript:void(0)" onclick="javascript:getRelate(\''.$tagArr[$i].'\')">&nbsp'.$tagArr[$i].'&nbsp</a>',$string,$count);
			$result['count'][$i] = $count;	
			$string = $result['resultStr']; 		
		}
		return $result;
	 }
	
	
	/**
	*  Check if its duplicate tag
	*
	* @param  $tag, $tagArray
	* @return  $boolean
	*/
	public function _isDuplicateTag($tag, $tagArray)
	{
		$cnt = count($tagArray);
		$exists = false;
		
		for($i=0; $i<$cnt; $i++){
			echo  $tagArray[$i]."==".$tag.'<br>';
			$exists = strstr($tagArray[$i], $tag);
			
			if($exists != false){
				return true;
			}				
		}			
		return false;
	}
	
	
	/**
	*	Remove duplicate tag by order in table tags, beacuse the prevous tags got higher priority.
	*
	* @param
	* @return   $tagArr
	*/
	private function _removeDuplicateTags($arrayTag)
	{
		$cnt = count($arrayTag);
		for($i=$cnt-1; $i>=0; $i--){
			// if( $this->_isDuplicateTag($tagArr[$i], $tagArr) ){
				// echo $tagArr[$i];
				// $tempArr = array_pop($tagArr);
				// echo $this->_isDuplicateTag($tagArr[$i], $tempArr).'<br>';
				// unset($tagArr[$i]);
			// }
			for($j=0; $j<$i; $j++){
				$exists = strstr($arrayTag[$j], $arrayTag[$i]);
				if($exists != false){
					$this->_arrayRemove($arrayTag,$i);					
					continue;
				}
			}                                                       
			
		}
		
		return $arrayTag;		
	}

	/**
	*	Remove value from an array.
	*
	* @param &$arr, $offset
	* @return
	*/
	private function _arrayRemove(&$arr,$offset){  
		array_splice($arr,$offset,1);  
	} 
	
	
	/**
	*	Sort tagArray by tag lentth.
	*
	* @param $tagsArray
	* @return
	*/
	public function sortTags($tagsArray)
	{
		usort($tagsArray,array('SeparateTags','_lengthCmp'));
		return $tagsArray;
	}
	
	/**
	*	Help sortTags to sort tagArray by tag lentth.
	*
	* @param $tagA, $tagB 
	* @return 
	*/
	private function _lengthCmp( $tagA, $tagB ) {
	   return strlen($tagB)-strlen($tagA) ;
	}
	
	/**
	*	Better way to replace.
	*
	* @param $tagA, $tagB 
	* @return 
	*/
	public function betterReplace()
	{
		//首先匹配最长的	
		//把匹配完毕的分离出来
		//继续匹配没有分离出的文本
		//最后从新拼接
				
	}
	
	
	
	

}//end of class SeparateTags

?>   












